/* babylonjs可用包
 * @babylonjs/core - Babylon 的核心。
 * @babylonjs/materials - Babylon 支持的高级材料的集合。
 * @babylonjs/loaders - Babylon 的所有官方加载器（OBJ、STL、glTF）
 * @babylonjs/post-processes - Babylon 的后期处理。
 * @babylonjs/procedural-textures - 官方支持的程序纹理
 * @babylonjs/serializers - 场景/网格序列化器。
 * @babylonjs/gui -Babylon.js GUI 模块。
 * @babylonjs/inspector - 独立的Babylon.js 查看器。
 */

import {
	Engine,
	Scene,
	SceneLoader,
	FreeCamera,
	ArcRotateCamera,
	DirectionalLight,
	HemisphericLight,
	SpotLight,
	PointLight,
	Vector3,
	MeshBuilder,
	StandardMaterial,
	Color3,
	Color4,
	Texture,
	CubeTexture,
	PointerEventTypes,
	Animation
} from "@babylonjs/core"; // 按需引入
// import * as BABYLON from "@babylonjs/core/Legacy/legacy";// 全部引入

import "@babylonjs/loaders/glTF"
// import "@babylonjs/loaders/OBJ"

import {
	data
} from "./data.js"; // 模型的数据源

import {
	execution
} from "./execution.js"; // 模型的执行函数

import Vue from 'vue'

// canvas画布
// key公厕编号
// resData坑位数据
// isCreateSprite是否创建精灵图标
// 切换视角ref
// 图例ref
let loadScene = function (
	canvas,
	key,
	resData,
	isCreateSprite,
	homeChange,
	legend
) {
	let self = Vue.prototype;
	let engine, scene, camera, sceneToRender;

	/* 判断公厕的模型参数是否配置 */
	let keyArr = [];
	for (var k in data) {
		keyArr.push(k);
	}
	// console.log(canvas, homeChange, legend)
	if (keyArr.indexOf(key) === -1) {
		canvas ? canvas.style.display = 'none' : '';
		homeChange ? homeChange.style.display = 'none' : '';
		legend ? legend.style.display = 'none' : '';
		self.$notify({
			title: '提示',
			message: '尚未配置该公厕的模型参数，无法使用，请联系管理员！',
			type: 'error',
			duration: 10 * 1000,
			offset: 50,
			position: 'top-right'
		});
		// self.$message.warning('尚未配置该公厕的模型参数，无法使用，请联系管理员！')
		return {
			engine,
			scene,
			camera,
			sceneToRender
		};
	} else {
		canvas ? canvas.style.display = 'block' : '';
		homeChange ? homeChange.style.display = 'flex' : '';
		legend ? legend.style.display = 'flex' : '';
	}
	/* 判断浏览器 */
	if (!!window.ActiveXObject || ("ActiveXObject" in window)) { // IE
		self.$notify({
			title: '提示',
			message: '该浏览器不支持，请升级浏览器或者更换主流浏览器（如：谷歌、360(极速模式下)等。）',
			type: 'error'
		});
		return {
			engine,
			scene,
			camera,
			sceneToRender
		};
	}

	/* 创建并加载3D引擎 */
	engine = new Engine(
		canvas, //指定画布/WebGL上下文
		true, //启用抗锯齿？
		{
			preserveDrawingBuffer: true,
			stencil: true,
			disableWebGL2Support: false
		}
	);

	/* 创建场景对象 */
	scene = new Scene(engine);
	// scene.clearColor = new Color4(125/255, 252/255, 244/255, 0);// 改变场景背景颜色

	/* 自定义创建一个网格/物体 mesh（该步骤非必须） */
	// 1. 创建地面
	// 2. 创建球
	// 3. 创建天空
	CreateSky(scene);

	/* 创建并返回场景函数 */
	let createScene = function () {
		/* 创建摄影机 */
		camera = new ArcRotateCamera(
			"Camera", // 名称
			-Math.PI / 2, // alpha
			Math.PI / 2.5, // beta
			15, // 半径radius
			new Vector3(0, 0, 0), // 目标位置position
			scene // 场景
		);
		camera.setTarget(Vector3.Zero()); // 这会将摄影机指向场景原点
		camera.attachControl(canvas, true); // 这会将相机连接到画布上，true/false: noPreventDefault 是否阻止元素的默认事件.
		// camera.inputs.attached.mousewheel.detachControl(canvas);// 无法缩放了

		/* 创建灯光 */
		// let Light1 = new DirectionalLight("Light1", new Vector3(0, 0, 0), scene);
		// Light1.direction = new Vector3(-0.5, 0.38, 0.67);
		// Light1.position = camera.position;
		// Light1.parent = camera;
		// Light1.diffuse = Color3.White();

		let Light2 = new HemisphericLight('Light2', new Vector3(1, 1, 0), scene);
		Light2.diffuse = Color3.White(); // 颜色
		Light2.intensity = 1.00; // 亮度
		// Light2.setEnabled(false);// 禁掉光的使用，传入true来开启使用

		// let Light3 = new SpotLight("Light3", new Vector3(0, 30, -10), new Vector3(0, -1, 0), Math.PI / 3, 2, scene);
		// Light3.intensity = 0.5; // 调整intensity属性调整光的亮度，默认值为1
		// Light3.range = 100; // 整range属性来设置光的照射范围
		// Light3.diffuse = Color3.White();

		// let Light4 = new PointLight("Light4", new Vector3(0, 1, -1), scene);
		// Light4.diffuse = Color3.White();

		/* 导入模型 */
		let promises = [];
		promises.push(
			// Append AppendAsync ImportMesh LoadAssetContainer ImportAnimations
			SceneLoader.AppendAsync(
				data[key].filePath, // 模型文件路径
				data[key].fileName, // 模型文件名称
				scene
			)
		)
		Promise.all(promises).then(function (e) {
			console.log('新建3D场景：===>>', scene);
			// 初始化，调整到最佳位置
			ChangeBestView(
				scene,
				camera,
				data[key].position,
				data[key].target
			)
			// 开启/关闭相机的自动旋转
			camera.useAutoRotationBehavior = false;
			// 执行函数
			execution(scene, key, resData, isCreateSprite)
		})


		// engine.displayLoadingUI();// 加载资源时显示loding
		engine.hideLoadingUI(); // 加载资源时隐藏loding
		scene.executeWhenReady(function () {
			// engine.hideLoadingUI();
		});

		return scene;
	};

	/* 第五步：调用create_scene函数 */
	sceneToRender = createScene();

	/* 循环渲染场景 */
	engine.runRenderLoop(function () {
		sceneToRender.render();
	});

	/* 添加、监听鼠标事件 */
	scene.onPointerObservable.add(function (pointerInfo) {

		// POINTERDOUBLETAP 鼠标双击
		// POINTERDOWN 鼠标down
		// POINTERMOVE 鼠标move
		// POINTERPICK 鼠标up+down
		// POINTERTAP 鼠标up+down
		// POINTERUP 鼠标up
		// POINTERWHEEL 鼠标滑轮

		switch (pointerInfo.type) {
			case PointerEventTypes.POINTERDOWN: // 鼠标DOWN事件
				if (camera && scene) {
					let xyz = '[' +
						pointerInfo.pickInfo.pickedPoint._x + ',' +
						pointerInfo.pickInfo.pickedPoint._y + ',' +
						pointerInfo.pickInfo.pickedPoint._z +
						']';
					console.log('xyz坐标：', xyz)
					console.log(
						pointerInfo,
						pointerInfo.pickInfo.hit ? pointerInfo.pickInfo.pickedMesh.name : false
					)
					// console.log('camera：', BABYLONJS_camera)
					console.log('camera-position：', {
						"x": camera.position.x,
						"y": camera.position.y,
						"z": camera.position.z
					})
					console.log('camera-target', {
						"x": camera.target.x,
						"y": camera.target.y,
						"z": camera.target.z
					})
				}
				break;
			case PointerEventTypes.POINTERUP: // 鼠标UP事件
				break;
			case PointerEventTypes.POINTERMOVE: // 鼠标移动事件，提示文字信息
				break;
		}
	});

	/* 画布/窗口调整大小事件处理程序 */
	window.addEventListener("resize", function () {
		engine.resize();
	});

	return {
		engine,
		scene,
		camera,
		sceneToRender
	};
};

export {
	loadScene,
	CreateSky,
	ChangeBestView,
};

/* 创建天空 */
function CreateSky(
	scene
) {
	let skybox = MeshBuilder.CreateBox("skyBox", {
		size: 1600
	}, scene);
	let skyboxMaterial = new StandardMaterial("skyBox", scene);
	skyboxMaterial.backFaceCulling = false;
	skyboxMaterial.reflectionTexture = new CubeTexture(window.serverConfig.resources+"/images/textures/skybox/skybox", scene);
	skyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE;
	skyboxMaterial.diffuseColor = new Color3(83 / 255, 166 / 255, 197 / 255); // #53A6C5 rgb(83 166 197)
	skyboxMaterial.specularColor = new Color3(0, 0, 0);
	skybox.material = skyboxMaterial;
}

/* 
 * 点击切换到最佳视角（动画） 
 * scene
 * camera
 * position         最佳位置，{x:？,y:？,z:？}
 * target           摄像机目标位置，{x:?,y:?,z:?}
 */
function ChangeBestView(
	scene, camera, position, target
) {

	// 是否自动旋转
	camera.useAutoRotationBehavior = false;
	// 设置 每秒帧数
	var frameRate = 20;
	/* position */
	// 让摄像机移动
	var movein = new Animation(
		"movein_BestView_position",
		"position",
		frameRate,
		Animation.ANIMATIONTYPE_VECTOR3,
		Animation.ANIMATIONLOOPMODE_CONSTANT
	);
	// movein_keys
	var movein_keys = [];
	let falgX = camera.position._x === position.x;
	let falgY = camera.position._y === position.y;
	let falgZ = camera.position._z === position.z;
	if (falgX && falgY && falgZ) {
		movein_keys.push({
			frame: 0,
			value: new Vector3(position.x, position.y, position.z)
		});
	} else {
		movein_keys.push({
			frame: 0,
			value: new Vector3(camera.position._x, camera.position._y, camera.position._z)
		});
		movein_keys.push({
			frame: 1 * frameRate,
			value: new Vector3(position.x, position.y, position.z)
		});
	}
	// setKeys
	movein.setKeys(movein_keys);

	/* target */
	// 让摄像机移动
	var movein2 = new Animation(
		"movein_BestView_target",
		"target",
		frameRate,
		Animation.ANIMATIONTYPE_VECTOR3,
		Animation.ANIMATIONLOOPMODE_CONSTANT
	);
	// movein_keys
	var movein_keys2 = [];
	let falgX2 = camera.target._x === target.x;
	let falgY2 = camera.target._y === target.y;
	let falgZ2 = camera.target._z === target.z;
	if (falgX2 && falgY2 && falgZ2) {
		movein_keys2.push({
			frame: 0,
			value: new Vector3(target.x, target.y, target.z)
		});
	} else {
		movein_keys2.push({
			frame: 0,
			value: new Vector3(camera.target._x, camera.target._y, camera.target._z)
		});
		movein_keys2.push({
			frame: 1 * frameRate,
			value: new Vector3(target.x, target.y, target.z)
		});
	}
	// setKeys
	movein2.setKeys(movein_keys2);

	// beginDirectAnimation 参数：target，动画，开始动画的帧，动画结束的帧，是否循环
	scene.beginDirectAnimation(camera, [movein, movein2], 0, 25 * frameRate, false);
}